﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using OBiCMS.Dean.Edwards;

/*
    Copyright (C) 2010 Officebroker.com LTD.
    Neil Cadman, Alex Welding, Andrew Coombs, Jan Rygielski
    Sir Robert Peel Mill, Mill Lane, Staffordshire, Fazely, B78 3QD, England

    This file is part of OBiCMSFramework.

    OBiCMSFramework is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    OBiCMSFramework is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License (GNU AGPL)
    along with OBiCMSFramework.  If not, see <http://www.gnu.org/licenses/>.
 */

namespace OBiCMSFramework
{
    public class StaticObjects
    {
        // Private Varaibles
        private static Boolean _httpHandlerLive = true;
        private static Boolean _getURLRewriteJobs = true;
        private static javascriptPack _packJavascript;
        private static List<String> _connectionStrings = new List<String>();
        private static StringBuilder _errorLog = new StringBuilder();
        private static String _savedStatesLocation;

        // Public Properties
        public static List<String> ConnectionStrings
        {
            get { return _connectionStrings; }
        }

        // Internal Properties
        internal static Boolean HTTPhandlerLive
        {
            get { return _httpHandlerLive; }
            set { _httpHandlerLive = value; }
        }
        internal static Boolean GetURLRewriteJobs
        {
            get { return _getURLRewriteJobs; }
            set { _getURLRewriteJobs = value; }
        }
        internal static javascriptPack PackJavascript
        {
            get { return _packJavascript; }
            set { _packJavascript = value; }
        }
        internal static String ErrorLog
        { get { return _errorLog.ToString(); } }
        internal static String SavedStatesLocation
        {
            get { return _savedStatesLocation; }
            set { _savedStatesLocation = value;  }
        }

        // Internal Methods
        internal static void AppendErrorLog(OBiHTTPHandler.CMSException error)
        {
            Exception e;
            StringBuilder newError = new StringBuilder();

            newError.Append("CMS Error...<br/><br/>" + Environment.NewLine +
                             "Url : Threaded error.<br/>" + Environment.NewLine +
                             "Message : " + error.Message + "<br/>" + Environment.NewLine +
                             "Source : " + error.Source + "<br/>" + Environment.NewLine +
                             "Trace : " + error.StackTrace + "<br/><br/>" + Environment.NewLine);

            e = error.InnerException;

            while (e != null)
            {
                newError.Append("Inner Exception :<br/>" + Environment.NewLine +
                                 "Inner Exception Message : " + e.Message + "<br/>" + Environment.NewLine +
                                 "Inner Exception Source : " + e.Source + "<br/>" + Environment.NewLine +
                                 "Inner Exception Trace : " + e.StackTrace + "<br/>" + Environment.NewLine);

                e = e.InnerException;
            }

            newError.Append("<br /><br /><br />" + Environment.NewLine + Environment.NewLine + Environment.NewLine);
            _errorLog.Append(newError);
        }
        internal static void DeSerialize(String file)
        {
            DeSerialize(new String[] { file });
        }
        internal static void DeSerialize(String[] files)
        {
            Stream LoadSettingsStream = null;

            foreach (String filename in files)
            {
                if (File.Exists(filename))
                {
                    LoadSettingsStream = File.OpenRead(filename);
                    BinaryFormatter LoadSettingsFormatter = new BinaryFormatter();
                    switch (System.IO.Path.GetExtension(filename).ToLower())
                    {
                        case ".widget":
                            WidgetBase newWidget = (WidgetBase)LoadSettingsFormatter.Deserialize(LoadSettingsStream);
                            newWidget.BeginAutoLoad();
                            BasePage.CachedWidgets.Add(newWidget);
                            break;
                        case ".template":
                            Template newTemplate = (Template)LoadSettingsFormatter.Deserialize(LoadSettingsStream);
                            newTemplate.BeginAutoLoad();
                            newTemplate.AddToGlobalCSSList();

                            Template.CachedTemplates.Add(newTemplate);
                            Template.CachedTemplatesHash.Add(newTemplate.ID, newTemplate);
                            break;
                        case ".csssnippet":
                            BasePage.CSSSnippet newSnippet = (BasePage.CSSSnippet)LoadSettingsFormatter.Deserialize(LoadSettingsStream);
                            BasePage.CachedCssSnippets.Add(newSnippet);
                            BasePage.CachedCssSnippetsHash.Add(newSnippet.ID, newSnippet);
                            break;
                    }
                }
            }

            LoadSettingsStream.Close();
            LoadSettingsStream.Dispose();
            LoadSettingsStream = null;
        }
        internal static void Serialize(Object objectToSerialize, String filename, String path)
        {
            BinaryFormatter SettingsFormatter = new BinaryFormatter();
            Stream SettingsStream = File.Create(path + filename);
            SettingsFormatter.Serialize(SettingsStream, objectToSerialize);
            SettingsStream.Flush();
            SettingsStream.Close();
            SettingsFormatter = null;
            SettingsStream.Dispose();
            SettingsStream = null;
        }

        // Public Methods

        /// <summary>
        /// Adds Tables and Rows to a DataSet using the ConnectionStrings provided in the webconfig.
        /// </summary>
        /// <param name="sql">Query that will be run on the database</param>
        /// <returns>New Instance of a DataSet</returns>
        public static DataSet GetDataset(String sql)
        {
            DataSet ds = new DataSet();

            foreach (String conString in StaticObjects.ConnectionStrings)
            {
                SqlConnection sqlConnection = new SqlConnection(conString);

                if (sqlConnection.State == ConnectionState.Closed)
                    sqlConnection.Open();

                SqlDataAdapter da = new SqlDataAdapter(sql, sqlConnection);
                da.Fill(ds);

                if (sqlConnection.State == ConnectionState.Open)
                    sqlConnection.Close();

                return ds;
            }

            return ds;
        }
        public static void UpdateDatabase(String sql)
        {
            foreach (String conString in StaticObjects.ConnectionStrings)
            {
                SqlConnection sqlConnection = new SqlConnection(conString);

                if (sqlConnection.State == ConnectionState.Closed)
                    sqlConnection.Open();

                SqlCommand sqlUpdate = new SqlCommand(sql, sqlConnection);
                sqlUpdate.ExecuteNonQuery();

                if (sqlConnection.State == ConnectionState.Open)
                    sqlConnection.Close();

                return;
            }
        }

        // Internal Classes
        internal static class RandomFactory
        {
            private static Random globalRandom = new Random();

            public static Random Create()
            {
                lock (globalRandom)
                {
                    Random newRandom = new Random(globalRandom.Next());
                    return newRandom;
                }
            }
        }

        // Public Struct
        internal struct javascriptPack
        {
            // Private Variables
            private Boolean _pack;
            private Boolean _fastDecode;
            private Boolean _specialChars;
            private ECMAScriptPacker.PackerEncoding _encoding;

            // Public Properties
            public Boolean Pack
            { get { return _pack; } }
            public Boolean FastDecode
            { get { return _fastDecode; } }
            public Boolean SpecialChars
            { get { return _specialChars; } }
            public ECMAScriptPacker.PackerEncoding Encoding
            { get { return _encoding; } }

            // Public Constructors
            public javascriptPack(Boolean pack, ECMAScriptPacker.PackerEncoding encoding, Boolean fastDecode, Boolean specialChars)
            {
                _pack = pack;
                _encoding = encoding;
                _fastDecode = fastDecode;
                _specialChars = specialChars;
            }

        }

    }
}
